package com.supply.dl.utils.utils;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.format.Formatter;
import com.supply.dl.utils.StringUtils;

import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 类描述：　[文件相关操作相关的工具类]<br/>
 * 项目名称：[AndroidArchitecture]<br/>
 * 包名：　　[com.yeung.architecture.utils]<br/>
 * 创建人：　[杨挺]<br/>
 * 创建时间：[2016/07/28 0006 14:51]<br/>
 * 版本：　　[v1.0.0]<br/>
 */
public class FileUtils
{
	/**
	 * 将以一个远端url路径转换成本地的图片名称
	 */
	public static String getFileNameFormUrl(String imageUrl)
	{
		return MD5.md5Hex(imageUrl);
	}

	public static StringBuilder read(Reader stream)
	{
		StringBuilder fileContent = new StringBuilder("");
		BufferedReader reader = null;
		try
		{
			reader = new BufferedReader(stream);
			String line;
			while ((line = reader.readLine()) != null)
			{
				fileContent.append(line);
			}
			reader.close();
			return fileContent;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (reader != null)
			{
				try
				{
					reader.close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * 读取指定的文件的里的文本内容
	 * @param filePath 文件路径
	 * @return 文件里的文本
	 */
	public static StringBuilder readFile(String filePath)
	{
		return readFile(filePath);
	}

	public static boolean readFileShareInfo(String filePath, boolean defaultValue)
	{
		StringBuilder stringBuffer = readFile(filePath, false);
		if (stringBuffer == null)
			return defaultValue;
		String s = stringBuffer.toString();
		if (StringUtils.isBlank(s))
			return defaultValue;
		if (s.equals("0"))
			return false;
		if (s.equals("1"))
			return true;
		return defaultValue;
	}

	/**
	 * 读取指定的文件的里的文本内容
	 * @param filePath 文件路径
	 * @return 文件里的文本
	 */
	public static StringBuilder readFile(String filePath, boolean isUpdataLastTime)
	{
		try
		{
			File file = new File(filePath);
			if (file.exists())
			{
				if (isUpdataLastTime)
					file.setLastModified(System.currentTimeMillis());
				return readFile(new FileInputStream(file));
			}
		}
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 复制单个文件
	 * @param oldPath String 原文件路径 如：c:/fqf.txt
	 * @param newPath String 复制后路径 如：f:/fqf.txt
	 * @return boolean
	 */
	public static boolean copyFile(String oldPath, String newPath)
	{
		InputStream inStream = null;
		FileOutputStream fs = null;
		try
		{
			int byteRead;
			File oldFile = new File(oldPath);
			if (oldFile.exists())
			{
				//文件存在时
				inStream = new FileInputStream(oldPath); //读入原文件
				fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1444];
				while ((byteRead = inStream.read(buffer)) != -1)
				{
					fs.write(buffer, 0, byteRead);
				}
			}
			return true;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			closeStream(inStream);
			closeStream(fs);
		}
		return false;
	}

	private static void closeStream(Closeable closeable)
	{
		if (closeable != null)
		{
			try
			{
				closeable.close();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}

	public static byte[] readFileByteArray(String filePath)
	{
		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();

		FileInputStream inputStream = null;
		try
		{
			inputStream = new FileInputStream(filePath);

			byte[] buffer = new byte[1024];
			int length;
			while ((length = inputStream.read(buffer)) != -1)
			{
				arrayOutputStream.write(buffer, 0, length);
			}

			return arrayOutputStream.toByteArray();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				arrayOutputStream.close();
				if (inputStream != null)
				{
					inputStream.close();
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 读取指定的文件的里的文本内容
	 */
	public static StringBuilder readFile(InputStream stream)
	{
		StringBuilder fileContent = new StringBuilder("");
		BufferedReader reader = null;
		try
		{
			reader = new BufferedReader(new InputStreamReader(stream));
			String line;
			while ((line = reader.readLine()) != null)
			{
				fileContent.append(line);
			}
			reader.close();
			return fileContent;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (reader != null)
			{
				try
				{
					reader.close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * 将字符串写入指定的文件的中
	 * @param filePath 文件路径
	 * @param content 要写入的内容
	 * @param append 写入文件末尾处
	 */
	public static boolean writeFile(String filePath, String content, boolean append)
	{
		FileWriter fileWriter = null;
		try
		{
			makeFile(filePath);
			fileWriter = new FileWriter(filePath, append);
			fileWriter.write(content);
			fileWriter.close();
			return true;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (fileWriter != null)
			{
				try
				{
					fileWriter.close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
		return false;
	}

	/**
	 * 将指定的流写入指定的路径
	 * @param filePath 要写入的文件路径
	 * @param stream 流
	 */
	public static boolean writeFile(String filePath, InputStream stream)
	{
		OutputStream o = null;
		try
		{
			//			deleteFile(filePath);
			// 标识是临时文件
			File tempFile = new File(filePath + ".temp");
			if (!tempFile.exists())
			{
				makeFile(tempFile.toString());
			}
			o = new FileOutputStream(tempFile);
			byte data[] = new byte[1024];
			int length = -1;
			while ((length = stream.read(data)) != -1)
			{
				o.write(data, 0, length);
			}
			o.flush();
			// 下载完成后，更改后缀名
			return tempFile.renameTo(new File(filePath));
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			if (o != null)
			{
				try
				{
					o.close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
			if (stream != null)
			{
				try
				{
					stream.close();
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		}
		return false;
	}

	/**
	 * 根据一个路径读取文件里的内容分行存入List中
	 */
	public static List<String> readFileToList(String filePath)
	{
		File file = new File(filePath);
		List<String> fileContent = new ArrayList<String>();
		if (file.isFile())
		{
			BufferedReader reader = null;
			try
			{
				reader = new BufferedReader(new FileReader(file));
				String line;
				while ((line = reader.readLine()) != null)
				{
					fileContent.add(line);
				}
				reader.close();
				return fileContent;
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				if (reader != null)
				{
					try
					{
						reader.close();
					}
					catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			}
		}
		return null;
	}

	/**
	 * 根据一个流里的内容分行存入List中
	 */
	public static List<String> readInputStreamToList(InputStream input)
	{
		List<String> fileContent = new ArrayList<String>();
		if (input != null)
		{
			BufferedReader reader = null;
			try
			{
				reader = new BufferedReader(new InputStreamReader(input));
				String line;
				while ((line = reader.readLine()) != null)
				{
					fileContent.add(line);
				}
				reader.close();
				return fileContent;
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				if (reader != null)
				{
					try
					{
						reader.close();
					}
					catch (Exception e)
					{
						e.printStackTrace();
					}
				}
			}
		}
		return null;
	}

	private final static String FILE_EXTENSION_SEPARATOR = ".";

	/**
	 * 获得文件名(以文件的第一个.)
	 * <pre>
	 *      getFileNameWithoutExtension(null)               =   null
	 *      getFileNameWithoutExtension("")                 =   ""
	 *      getFileNameWithoutExtension("   ")              =   "   "
	 *      getFileNameWithoutExtension("abc")              =   "abc"
	 *      getFileNameWithoutExtension("a.mp3")            =   "a"
	 *      getFileNameWithoutExtension("a.b.rmvb")         =   "a.b"
	 *      getFileNameWithoutExtension("c:\\")              =   ""
	 *      getFileNameWithoutExtension("c:\\a")             =   "a"
	 *      getFileNameWithoutExtension("c:\\a.b")           =   "a"
	 *      getFileNameWithoutExtension("c:a.txt\\a")        =   "a"
	 *      getFileNameWithoutExtension("/home/admin")      =   "admin"
	 *      getFileNameWithoutExtension("/home/admin/a.txt/b.mp3")  =   "b"
	 * </pre>
	 * @return file name from path, not include suffix
	 * @see
	 */
	public static String getFileNameWithoutExtension(String filePath)
	{
		if (StringUtils.isEmpty(filePath))
		{
			return filePath;
		}

		int extenPosi = filePath.lastIndexOf(FILE_EXTENSION_SEPARATOR);
		int filePosi = filePath.lastIndexOf(File.separator);
		if (filePosi == -1)
		{
			return (extenPosi == -1 ? filePath : filePath.substring(0, extenPosi));
		}
		else
		{
			if (extenPosi == -1)
			{
				return filePath.substring(filePosi + 1);
			}
			else
			{
				return (filePosi < extenPosi ? filePath.substring(filePosi + 1, extenPosi) : filePath.substring(filePosi + 1));
			}
		}
	}

	/**
	 * 获得文件名(以文件的最后的.)
	 * <pre>
	 *      getFileName(null)               =   null
	 *      getFileName("")                 =   ""
	 *      getFileName("   ")              =   "   "
	 *      getFileName("a.mp3")            =   "a.mp3"
	 *      getFileName("a.b.rmvb")         =   "a.b.rmvb"
	 *      getFileName("abc")              =   "abc"
	 *      getFileName("c:\\")              =   ""
	 *      getFileName("c:\\a")             =   "a"
	 *      getFileName("c:\\a.b")           =   "a.b"
	 *      getFileName("c:a.txt\\a")        =   "a"
	 *      getFileName("/home/admin")      =   "admin"
	 *      getFileName("/home/admin/a.txt/b.mp3")  =   "b.mp3"
	 * </pre>
	 * @return file name from path, include suffix
	 */
	public static String getFileName(String filePath)
	{
		if (StringUtils.isEmpty(filePath))
		{
			return filePath;
		}

		int filePosi = filePath.lastIndexOf(File.separator);
		if (filePosi == -1)
		{
			return filePath;
		}
		return filePath.substring(filePosi + 1);
	}

	/**
	 * 根据路径获取上一级的目录文件夹
	 * <pre>
	 *      getFolderName(null)               =   null
	 *      getFolderName("")                 =   ""
	 *      getFolderName("   ")              =   ""
	 *      getFolderName("a.mp3")            =   ""
	 *      getFolderName("a.b.rmvb")         =   ""
	 *      getFolderName("abc")              =   ""
	 *      getFolderName("c:\\")              =   "c:"
	 *      getFolderName("c:\\a")             =   "c:"
	 *      getFolderName("c:\\a.b")           =   "c:"
	 *      getFolderName("c:a.txt\\a")        =   "c:a.txt"
	 *      getFolderName("c:a\\b\\c\\d.txt")    =   "c:a\\b\\c"
	 *      getFolderName("/home/admin")      =   "/home"
	 *      getFolderName("/home/admin/a.txt/b.mp3")  =   "/home/admin/a.txt"
	 * </pre>
	 */
	public static String getFolderName(String filePath)
	{

		if (StringUtils.isEmpty(filePath))
		{
			return filePath;
		}

		int filePosi = filePath.lastIndexOf(File.separator);
		if (filePosi == -1)
		{
			return "";
		}
		return filePath.substring(0, filePosi);
	}

	/**
	 * 得到的文件后缀从路径
	 * <pre>
	 *      getFileExtension(null)               =   ""
	 *      getFileExtension("")                 =   ""
	 *      getFileExtension("   ")              =   "   "
	 *      getFileExtension("a.mp3")            =   "mp3"
	 *      getFileExtension("a.b.rmvb")         =   "rmvb"
	 *      getFileExtension("abc")              =   ""
	 *      getFileExtension("c:\\")              =   ""
	 *      getFileExtension("c:\\a")             =   ""
	 *      getFileExtension("c:\\a.b")           =   "b"
	 *      getFileExtension("c:a.txt\\a")        =   ""
	 *      getFileExtension("/home/admin")      =   ""
	 *      getFileExtension("/home/admin/a.txt/b")  =   ""
	 *      getFileExtension("/home/admin/a.txt/b.mp3")  =   "mp3"
	 * </pre>
	 */
	public static String getFileExtension(String filePath)
	{
		if (StringUtils.isEmpty(filePath))
		{
			return filePath;
		}

		int extenPosi = filePath.lastIndexOf(FILE_EXTENSION_SEPARATOR);
		int filePosi = filePath.lastIndexOf(File.separator);
		if (extenPosi == -1)
		{
			return "";
		}
		else
		{
			if (filePosi >= extenPosi)
			{
				return "";
			}
			return filePath.substring(extenPosi + 1);
		}
	}

	/**
	 * Creates the directory named by the trailing filename of this file, including the complete directory path required to create this directory. <br/>
	 * <br/>
	 * <ul>
	 * <strong>Attentions�?/strong>
	 * <li>makeDirs("C:\\Users\\Trinea") can only create users folder</li>
	 * <li>makeFolder("C:\\Users\\Trinea\\") can create Trinea folder</li>
	 * </ul>
	 * @return true if the necessary directories have been created or the target directory already exists, false one of the directories can not be created.
	 * <ul>
	 * <li>if {@link FileUtils#getFolderName(String)} return null, return false</li>
	 * <li>if target directory already exists, return true</li>
	 * <li>return {@link File# makeFolder}</li>
	 * </ul>
	 */
	public static boolean makeDirs(String filePath)
	{
		//		String folderName = getFolderName(filePath);
		if (StringUtils.isEmpty(filePath))
		{
			return false;
		}

		File folder = new File(filePath);
		return (folder.exists() && folder.isDirectory()) || folder.mkdirs();
	}

	/**
	 * 创建一个文件夹
	 */
	public static boolean makeFolders(String filePath)
	{
		return makeDirs(filePath);
	}

	/**
	 * 判读一个路径是否是文件
	 */
	public static boolean isFileExist(String filePath)
	{
		if (StringUtils.isEmpty(filePath))
		{
			return false;
		}

		File file = new File(filePath);
		return (file.exists() && file.isFile());
	}

	/**
	 * 判断一个路径是否是文件夹
	 */
	public static boolean isFolderExist(String directoryPath)
	{
		if (StringUtils.isEmpty(directoryPath))
		{
			return false;
		}

		File dire = new File(directoryPath);
		return (dire.exists() && dire.isDirectory());
	}

	/**
	 * 删除一个文件或文件夹
	 * @param path 要删除的路径
	 */
	public static boolean deleteFile(String path)
	{
		try
		{

			if (StringUtils.isEmpty(path))
			{
				return true;
			}

			File source = new File(path);
			if (!source.exists())
				return true;
			final File file = new File(source.getAbsolutePath() + System.currentTimeMillis());
			source.renameTo(file);
			if (file.exists())
			{
				if (file.isFile())
				{
					return file.delete();
				}
				else if (file.isDirectory())
				{
					for (File f : file.listFiles())
					{
						if (f.isFile())
						{
							f.delete();
						}
						else if (f.isDirectory())
						{
							deleteFile(f.getAbsolutePath());
						}
					}
					return file.delete();
				}
				return false;
			}
			return true;
		}
		catch (Exception e)
		{
			return false;
		}
	}

	/**
	 * 获取指定文件夹内所有文件大小的和
	 * @param file file
	 * @return size
	 */
	public static long getFolderSize(File file)
	{
		long size = 0;
		try
		{
			File[] fileList = file.listFiles();
			for (File aFileList : fileList)
			{
				if (aFileList.isDirectory())
				{
					size = size + getFolderSize(aFileList);
				}
				else
				{
					size = size + aFileList.length();
				}
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return size;
	}

	/**
	 * 获取一个文件的大小
	 * @return 长度以字节为单位
	 */
	public static long getFileSize(String path)
	{
		if (StringUtils.isEmpty(path))
		{
			return -1;
		}
		File file = new File(path);
		return (file.exists() && file.isFile() ? file.length() : -1);
	}

	/**
	 * 创建文件
	 */
	public static boolean makeFile(String absFilePath)
	{
		if (StringUtils.isEmpty(absFilePath))
		{
			return false;
		}
		try
		{

			String newFileDirPath = getFolderName(absFilePath);
			makeDirs(newFileDirPath);

			return new File(absFilePath).createNewFile();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 获取文件MD5
	 * @param path
	 * @return
	 */
	public static String getFileMD5(String path) {
		File file = new File(path);
		return getFileMD5(file);
	}

	/**
	 * 获取文件MD5
	 * @param file
	 * @return
	 */
	public static String getFileMD5(File file) {
		if (!file.isFile()) {
			return null;
		}
		MessageDigest digest = null;
		FileInputStream in = null;
		byte buffer[] = new byte[1024];
		int len;
		try {
			digest = MessageDigest.getInstance("MD5");
			in = new FileInputStream(file);
			while ((len = in.read(buffer, 0, 1024)) != -1) {
				digest.update(buffer, 0, len);
			}
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		BigInteger bigInt = new BigInteger(1, digest.digest());
		return bigInt.toString(16);
	}

	public static boolean writeFile(String path, Bitmap bitmap) {
		if (path == null || bitmap == null) {
			return false;
		}
		OutputStream out = null;
		try {
			File file = new File(path);
			if (!file.exists()) {
				makeFile(file.toString());
			}
			out = new FileOutputStream(file);
			bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
			out.flush();
			out.close();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (Exception e){
					e.printStackTrace();
				}
			}
			if (bitmap != null) {
				bitmap.recycle();
			}
		}
		return false;
	}

	public static String getFileShowLenth(Context context, String path) {
		if (path == null || path.equals("")) {
			return "0B";
		}
		File file = new File(path);
		return getFileShowLenth(context, file);
	}

	public static String getFileShowLenth(Context context, File file) {
		if (file == null || !file.exists()) {
			return "0B";
		}
		return getFileShowLenth(context, file.length());

	}

	public static String getFileShowLenth(Context context, long len) {
		return Formatter.formatFileSize(context.getApplicationContext(), len);
	}

	public static boolean playLocalVideo(Context context, String path) {
		if (path == null || path.length() == 0) {
			return false;
		}
		try {
			Intent intent = new Intent(Intent.ACTION_VIEW);
			String videoPath = "file://" + path;
			intent.setDataAndType(Uri.parse(videoPath), "video/*");
			intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			context.startActivity(intent);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}


	/**
	 * 保存照相后的图片，存放到指定位置，图片名字为当前拍照时间
	 * @param bitmap
	 * @return
	 */
	public static String saveImage(Bitmap bitmap){
		//保存图片到指定目录下
		File file = new File(Environment.getExternalStorageDirectory(), "supply/images/");
		if(!file.exists()){
			file.mkdir();
		}
		//将图片保存的名字设置为当前拍照的时间
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		String fileName = format.format(new Date());

		String filePathAndName=file.getPath() + File.separator + fileName + ".jpg";
		FileOutputStream stream = null;
		try {
			stream = new FileOutputStream(filePathAndName);
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
			stream.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(stream!=null){
					stream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return fileName;
	}

	/**
	 * 该方法用于获取指定路径 和 名字 的file
	 * @param fileName 图片文件的名字
	 * @return 图片文件的路径+名称
	 */
	public static File getFile(String fileName) {
//		File filePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "ylfood/images");
		File filePath = new File(Environment.getExternalStorageDirectory(), "supply/images");
		if (!filePath.exists()) {
			filePath.mkdirs();
		}
		String name=null;
		if (StringUtils.isEmpty(fileName)){
			//将图片保存的名字设置为当前拍照的时间
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
			name = format.format(new Date());
		}else {
			name=fileName;
		}
		File file = new File(filePath.getPath() + File.separator + name + ".jpg");
		return file;
	}

	/**
	 * Try to return the absolute file path from the given Uri
	 *
	 * @param context
	 * @param uri
	 * @return the file path or null
	 */
	public static String getRealFilePathToUri( final Context context, final Uri uri ) {
		if ( null == uri ) return null;
		final String scheme = uri.getScheme();
		String data = null;
		if ( scheme == null )
			data = uri.getPath();
		else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) {
			data = uri.getPath();
		} else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) {
			Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null );
			if ( null != cursor ) {
				if ( cursor.moveToFirst() ) {
					int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA );
					if ( index > -1 ) {
						data = cursor.getString( index );
					}
				}
				cursor.close();
			}
		}
		return data;
	}

}
